/*
 * @Descripttion:
 * @version:
 * @Author: sueRimn
 * @Date: 2025-05-25 01:55:56
 * @LastEditors: sueRimn
 * @LastEditTime: 2025-07-30 00:07:25
 */
#include "iic.h"
#include "gpio.h"
#include "stdio.h"

#define ICM_SCL_H //HAL_GPIO_WritePin(GPIOA,ICM_SCL_Pin,GPIO_PIN_SET)
#define ICM_SCL_L //HAL_GPIO_WritePin(GPIOA,ICM_SCL_Pin,GPIO_PIN_RESET)
#define ICM_SDA_H //HAL_GPIO_WritePin(GPIOA,ICM_SDA_Pin,GPIO_PIN_SET)
#define ICM_SDA_L //HAL_GPIO_WritePin(GPIOA,ICM_SDA_Pin,GPIO_PIN_RESET)

#define ICM_SDA_READ //HAL_GPIO_ReadPin(GPIOA,ICM_SDA_Pin)


static void IIC_Delay(unsigned short t)
{
	volatile uint16_t i = 0;
	volatile uint8_t j = 0;
	do
	{
		for(i;i < 1000;i++)
		{
			j++;
		}
	} while (t--);
}

/** */

void ICM_IIC_Init(void)
{
	ICM_SCL_H;
	ICM_SDA_H;
	IIC_Delay(1);
}

void ICM_IIC_Start(void)
{
	ICM_SDA_H;
	ICM_SCL_H;
	IIC_Delay(1);
	ICM_SDA_L;
	IIC_Delay(1);
	ICM_SCL_L;
	IIC_Delay(1);
}

void ICM_IIC_Stop(void)
{
	ICM_SDA_L;
	ICM_SCL_L;
	IIC_Delay(1);
	ICM_SCL_H;
	IIC_Delay(1);
	ICM_SDA_H;
	IIC_Delay(1);
}

//1:应答 0：非应答
void ICM_IIC_SendACK(uint8_t ACK)
{
	ICM_SCL_L;
	IIC_Delay(1);

	if (ACK == 1) ICM_SDA_L;
	else ICM_SDA_H;
	IIC_Delay(1);
	ICM_SCL_H;
	IIC_Delay(1);
	ICM_SCL_L;
	IIC_Delay(1);
}

//1:应答 0：非应答
uint8_t ICM_I2C_RecvACK(void)
{
	uint8_t i, ACK;
	ICM_SCL_L;
	
	IIC_Delay(1);

	ICM_SCL_H;
	IIC_Delay(1);
	for (i = 0;i < 255;i++)
	{
//		if (ICM_SDA_READ == 0)
//		{
//			ACK = 0;
//			break;
//		}
//		else
//			ACK = 1;
	}
	
	IIC_Delay(1);
	ICM_SCL_L;
	IIC_Delay(1);
	// if(ACK == 1)
	// 	printf("out time\r\n");
	return ACK;
}

//Data:要发送的数据
void ICM_IIC_Write_Byte(uint8_t Data)
{
	uint8_t i;
	for (i = 0;i < 8;i++)
	{
		if ((Data & 0x80) != 0)
			ICM_SDA_H;
		else
			ICM_SDA_L;
		IIC_Delay(1);
		ICM_SCL_H;
		IIC_Delay(1);
		ICM_SCL_L;
		IIC_Delay(1);
		Data = Data << 1;
	}
	ICM_I2C_RecvACK();
}

uint8_t ICM_IIC_Read_Byte(void)
{
	uint8_t num;
	uint8_t Data = 0;

	ICM_SCL_L;
	IIC_Delay(1);

	ICM_SDA_H;
	for (num = 0;num < 8;num++)
	{
		Data = Data << 1;
		IIC_Delay(1);

		ICM_SCL_L;
		IIC_Delay(1);

		ICM_SCL_H;
		IIC_Delay(1);
//		if (ICM_SDA_READ)
//			Data |= 0x01;

	}
	
	ICM_SCL_L;
	IIC_Delay(1);
	return Data;
}

void ICM_IIC_Write_Reg(uint8_t SlaveAddr, uint8_t REG_Addr, uint8_t Data)
{
	ICM_IIC_Start();                //起???信??
	ICM_IIC_Write_Byte(SlaveAddr);  //发送??????地址
	ICM_IIC_Write_Byte(REG_Addr);   //内部寄存器地址
	ICM_IIC_Write_Byte(Data);       //将???写入的数据
	ICM_IIC_Stop();                 //停???信号
}

//ICM IIC读取一??字节
//SlaveAddr:IIC器件地址
//REG_Addr:IIC器件寄存器地址
//Return:读取的数??
uint8_t ICM_IIC_Read_Reg(uint8_t SlaveAddr, uint8_t REG_Addr)
{
	uint8_t REG_data;
	ICM_IIC_Start();                	//起???信??
	ICM_IIC_Write_Byte(SlaveAddr);    	//发送??????地址+写信??
	ICM_IIC_Write_Byte(REG_Addr);     	//发送存储单元地址

	ICM_IIC_Start();                	//起???信??
	ICM_IIC_Write_Byte(SlaveAddr + 1); 	//发送??????地址+读信??
	REG_data = ICM_IIC_Read_Byte();       //读出寄存器数??
	ICM_IIC_SendACK(0);
	ICM_IIC_Stop();                 	//停???信号

	return REG_data;
}

void ICM_ICM_IIC_Read_RegS(uint8_t SlaveAddr, uint8_t REG_Addr, uint8_t *data, uint8_t len)
{

	ICM_IIC_Start();                	//起???信??
	ICM_IIC_Write_Byte(SlaveAddr);    	//发送??????地址+写信??
	ICM_IIC_Write_Byte(REG_Addr);     	//发送存储单元地址

	ICM_IIC_Start();                	//起???信??
	ICM_IIC_Write_Byte(SlaveAddr + 1); 	//发送??????地址+读信??
	for (uint8_t i = 0;i < len;i++)
	{
		*(data + i) = ICM_IIC_Read_Byte();       //读出寄存器数??
		if (i < len - 1)
			ICM_IIC_SendACK(1);
		else
			ICM_IIC_SendACK(0);
	}


	ICM_IIC_Stop();                 	//停???信号
}

/****************************************************************************************************************************/

#define INA_SCL_H HAL_GPIO_WritePin(GPIOB,IIC1_SCL_Pin,GPIO_PIN_SET)
#define INA_SCL_L HAL_GPIO_WritePin(GPIOB,IIC1_SCL_Pin,GPIO_PIN_RESET)
#define INA_SDA_H HAL_GPIO_WritePin(GPIOB,IIC1_SDA_Pin,GPIO_PIN_SET)
#define INA_SDA_L HAL_GPIO_WritePin(GPIOB,IIC1_SDA_Pin,GPIO_PIN_RESET)

#define INA_SDA_READ HAL_GPIO_ReadPin(GPIOB,IIC1_SDA_Pin)

void INA_SDA_OUT()
{
    // GPIO_InitTypeDef GPIO_InitStruct = { 0 };

    // GPIO_InitStruct.Pin = IIC1_SDA_Pin;
    // GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    // GPIO_InitStruct.Pull = GPIO_NOPULL;
    // GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    // HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}

void INA_SDA_IN()
{
    // GPIO_InitTypeDef GPIO_InitStruct = { 0 };

    // GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    // GPIO_InitStruct.Pin = IIC1_SDA_Pin;
    // GPIO_InitStruct.Pull = GPIO_NOPULL;
    // HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
}

void INA_IIC_Init(void)
{
    INA_SCL_H;
    INA_SDA_H;
    IIC_Delay(1);
}

void INA_IIC_Start(void)
{
    INA_SDA_H;
    INA_SCL_H;
    IIC_Delay(1);
    INA_SDA_L;
    IIC_Delay(1);
    INA_SCL_L;
    IIC_Delay(1);
}

void INA_IIC_Stop(void)
{
    INA_SDA_L;
    INA_SCL_L;
    IIC_Delay(1);
    INA_SCL_H;
    IIC_Delay(1);
    INA_SDA_H;
    IIC_Delay(1);
}


void INA_IIC_SendACK(uint8_t ACK)
{
    INA_SCL_L;
    IIC_Delay(1);

    if (ACK == 1) INA_SDA_L;
    else INA_SDA_H;
    IIC_Delay(1);
    INA_SCL_H;
    IIC_Delay(1);
    INA_SCL_L;
    IIC_Delay(1);
}

//1:应答 0：非应答
uint8_t INA_I2C_RecvACK(void)
{
    uint8_t i, ACK;
    INA_SCL_L;
    IIC_Delay(1);

    INA_SCL_H;
    IIC_Delay(1);

    INA_SDA_H;
    IIC_Delay(1);

    INA_SDA_IN();

    for (i = 0;i < 255;i++)
    {
        if (INA_SDA_READ == 0)
        {
            ACK = 0;
            break;
        }
        else
            ACK = 1;
    }
    INA_SDA_OUT();
    IIC_Delay(1);
    INA_SCL_L;
    IIC_Delay(1);
    // if(ACK == 1)
    // 	printf("out time\r\n");
    return ACK;
}

//Data:要发送的数据
void INA_IIC_Write_Byte(uint8_t Data)
{
    uint8_t i;
    for (i = 0;i < 8;i++)
    {
        if ((Data & 0x80) != 0)
            INA_SDA_H;
        else
            INA_SDA_L;
        IIC_Delay(1);
        INA_SCL_H;
        IIC_Delay(1);
        INA_SCL_L;
        IIC_Delay(1);
        Data = Data << 1;
    }
    INA_I2C_RecvACK();
}

uint8_t INA_IIC_Read_Byte(void)
{
    uint8_t num;
    uint8_t Data = 0;

    INA_SCL_L;
    IIC_Delay(1);
    
    INA_SDA_H;
    INA_SDA_IN();
    for (num = 0;num < 8;num++)
    {
        Data = Data << 1;
        IIC_Delay(1);

        INA_SCL_L;
        IIC_Delay(1);

        INA_SCL_H;
        IIC_Delay(1);
        if (INA_SDA_READ)
            Data |= 0x01;

    }
    INA_SDA_OUT();
    INA_SCL_L;
    IIC_Delay(1);
    return Data;
}

void INA_IIC_Write_Reg(uint8_t SlaveAddr, uint8_t REG_Addr, uint8_t Data)
{
    INA_IIC_Start();                //起???信??
    INA_IIC_Write_Byte(SlaveAddr);  //发送??????地址
    INA_IIC_Write_Byte(REG_Addr);   //内部寄存器地址
    INA_IIC_Write_Byte(Data);       //将???写入的数据
    INA_IIC_Stop();                 //停???信号
}

void INA_IIC_Write_Regs(uint8_t SlaveAddr, uint8_t REG_Addr, uint8_t *data,uint8_t len)
{
    INA_IIC_Start();                //起???信??
    INA_IIC_Write_Byte(SlaveAddr);  //发送??????地址
    INA_IIC_Write_Byte(REG_Addr);   //内部寄存器地址
	for (uint8_t i = 0; i < len; i++)
	{
		INA_IIC_Write_Byte(data[i]);       //将???写入的数据
	}

    INA_IIC_Stop();                 //停???信号
}


//INA IIC读取一??字节
//SlaveAddr:IIC器件地址
//REG_Addr:IIC器件寄存器地址
//Return:读取的数??
uint8_t INA_IIC_Read_Reg(uint8_t SlaveAddr, uint8_t REG_Addr)
{
    uint8_t REG_data;
    INA_IIC_Start();                	//起???信??
    INA_IIC_Write_Byte(SlaveAddr);    	//发送??????地址+写信??
    INA_IIC_Write_Byte(REG_Addr);     	//发送存储单元地址

    INA_IIC_Start();                	//起???信??
    INA_IIC_Write_Byte(SlaveAddr + 1); 	//发送??????地址+读信??
    REG_data = INA_IIC_Read_Byte();       //读出寄存器数??
    INA_IIC_SendACK(0);
    INA_IIC_Stop();                 	//停???信号

    return REG_data;
}

void INA_IIC_Read_Regs(uint8_t SlaveAddr, uint8_t REG_Addr, uint8_t *data, uint8_t len)
{

    INA_IIC_Start();                	//起???信??
    INA_IIC_Write_Byte(SlaveAddr);    	//发送??????地址+写信??
    INA_IIC_Write_Byte(REG_Addr);     	//发送存储单元地址

    INA_IIC_Start();                	//起???信??
    INA_IIC_Write_Byte(SlaveAddr + 1); 	//发送??????地址+读信??
    for (uint8_t i = 0;i < len;i++)
    {
        *(data + i) = INA_IIC_Read_Byte();       //读出寄存器数??
        if (i < len - 1)
            INA_IIC_SendACK(1);
        else
            INA_IIC_SendACK(0);
    }


    INA_IIC_Stop();                 	//停???信号
}